﻿using NPOI.POIFS.FileSystem;
using Simple.Repository.Models.ClassRoom;
using SixLabors.Fonts.Tables.AdvancedTypographic;
using SixLabors.ImageSharp.PixelFormats;
using ZXing;

namespace Simple.Services.System.ClassRoom
{
    public class ClassRoomService : BusinessBaseService
    {
        private readonly SimpleDbContext _context;
        private readonly CacheService _cacheService;

        public ClassRoomService(SimpleDbContext context,
                           ISimpleService services,
                           CacheService cacheService) : base(services)
        {
            _context = context;
            _cacheService = cacheService;
        }

        public async Task<ClassRoomOutputModel> GetAsync(ClassRoomSingleInputModel input)
        {
            if (!input.CRoomId.HasValue)
            {
                throw AppResultException.Status409Conflict("参数错误,教室Id参数不能为Null!");
            }

            var classRoomInfo = await _context.Set<GardenHouseClassRoom>().FirstOrDefaultAsync(c => c.Id == input.CRoomId);

            if (classRoomInfo == null)
            {
                throw AppResultException.Status409Conflict("未找到教室相关数据!");
            }

            var outResult = MapperHelper.Map<ClassRoomOutputModel>(classRoomInfo);
            return outResult;
        }

        public async Task<PageResultModel<ClassRoomOutputModel>> GetPageAsync(ClassRoomPageInputModel input)
        {
            var result = new PageResultModel<ClassRoomOutputModel>();
            var query = await OrganizationFilter(_context.Set<GardenHouseClassRoom>());

            // 根据条件查询
            if (!string.IsNullOrEmpty(input.CRoomName))
            {
                query = query.Where(m => EF.Functions.Like(m.CRoomName, $"%{input.CRoomName}%"));
            }

            // 根据条件查询
            if (!string.IsNullOrEmpty(input.CRoomCode))
            {
                query = query.Where(m => EF.Functions.Like(m.CRoomCode, $"%{input.CRoomCode}%"));
            }

            // 根据条件查询
            if (input.CRoomState.HasValue)
            {
                query = query.Where(m => m.CRoomState == input.CRoomState);
            }

            // 排序
            query = query.OrderByDescending(m => m.CreatedTime);

            // 获取总数量
            result.TotalRows = await query.CountAsync();

            // 分页查询
            query = query.Page(input.PageNo, input.PageSize);
            var classRoomOutResultList = await query.ToListAsync();
            result.Rows = MapperHelper.Map<List<ClassRoomOutputModel>>(classRoomOutResultList);

            result.SetPage(input);
            result.CountTotalPage();

            return result;
        }


        public async Task<int> AddAsync(ClassRoomOutputModel model)
        {
            if (await _context.Set<GardenHouseClassRoom>().AnyAsync(m => m.CRoomCode == model.CRoomCode))
            {
                throw AppResultException.Status409Conflict("已存在相同编码的教室，请重新填写！");
            }

            model.Id = Guid.NewGuid();
            var classRoom = MapperHelper.Map<GardenHouseClassRoom>(model);

            classRoom.QRcode = GetQRcodeSrc(classRoom.Id.ToString());//教室编号作为二维码的生成key

            await _context.AddAsync<GardenHouseClassRoom>(classRoom);

            return await _context.SaveChangesAsync();
        }


        private string GetQRcodeSrc(string cRoomCode)
        {
            var text = $"http://tianleletao.com:8101/?id={cRoomCode}";
            var result = string.Empty;
            var Qrcode = CreateQrCoder(BarcodeFormat.QR_CODE, text);//教室编号作为二维码的生成key
            using (var ms = new MemoryStream())
            {
                Qrcode.SaveAsPng(ms);
                byte[] imgBytes = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(imgBytes, 0, (int)ms.Length);
                result = "data:image/jpeg;base64," + Convert.ToBase64String(imgBytes);
            }
            return result;
        }

        /// <summary>
        /// 生成二维码
        /// </summary>
        /// <param name="value">value</param>
        /// <param name="width">二维码宽</param>
        /// <param name="height">二维码高</param>
        private Image CreateQrCoder(BarcodeFormat format, string value, int width = 200, int height = 200)
        {
            var writer = new ZXing.ImageSharp.BarcodeWriter<Rgba32>
            {
                Format = format,
                Options = new ZXing.QrCode.QrCodeEncodingOptions
                {
                    DisableECI = true,
                    CharacterSet = "UTF-8",
                    Width = width,
                    Margin = 0,
                    Height = height,

                }
            };
            var image = writer.WriteAsImageSharp<Rgba32>(value);
            return image;
        }

        public async Task<int> UpdateAsync(ClassRoomOutputModel model)
        {
            if (!model.Id.HasValue)
            {
                throw AppResultException.Status409Conflict("参数错误,教室Id参数不能为Null!");
            }

            if (await _context.Set<GardenHouseClassRoom>().AnyAsync(m => m.Id != model.Id && m.CRoomCode == model.CRoomCode))
            {
                throw AppResultException.Status409Conflict("已存在相同编码的教室，请重新填写！");
            }

            var classRoomInfo = await _context.Set<GardenHouseClassRoom>()
                .Where(m => model.Id == m.Id)
                .FirstOrDefaultAsync();

            if (classRoomInfo == null)
            {
                throw AppResultException.Status404NotFound("未找到教室相关数据，更新失败！");
            }

            MapperHelper.Map(model, classRoomInfo);

            classRoomInfo.QRcode = GetQRcodeSrc(classRoomInfo.Id.ToString());//教室编号作为二维码的生成key

            _context.Update(classRoomInfo);
            int ret = await _context.SaveChangesAsync();

            if (ret == 0)
            {
                throw AppResultException.Status200OK("更新记录数为0");
            }

            return ret;
        }

        public async Task<int> DeleteAsync(List<Guid?> ids)
        {
            if (ids == null || !ids.Any())
            {
                throw AppResultException.Status409Conflict("参数错误,教室Id参数不能为Null!");
            }

            var classRoomOutResultList = await _context.Set<GardenHouseClassRoom>()
                .Where(m => ids.Contains(m.Id))
                .ToListAsync();

            if (classRoomOutResultList == null || !classRoomOutResultList.Any())
            {
                throw AppResultException.Status404NotFound("未找到教室相关数据，删除失败！");
            }

            var relationClassList = _context.Set<SysClasses>().Where(c => ids.Contains(c.ClassroomId))?.ToList();
            if (relationClassList != null && relationClassList.Any())
            {
                throw AppResultException.Status404NotFound($"教室[{string.Join(",", relationClassList.Select(c => c.ClassroomName))}]已关联班级，删除失败！");
            }

            // 先更新数据库
            _context.RemoveRange(classRoomOutResultList);
            int ret = await _context.SaveChangesAsync();
            if (ret == 0)
            {
                throw AppResultException.Status200OK("更新记录数为0");
            }

            return ret;
        }

        public async Task<List<ClassRoomOutputModel>> GetAll()
        {
            var query = await OrganizationFilter(_context.Set<GardenHouseClassRoom>());
            var result = await query.ToListAsync();
            if (result == null || !result.Any())
            {
                return new List<ClassRoomOutputModel>();
            }

            return MapperHelper.Map<List<ClassRoomOutputModel>>(result) ?? new List<ClassRoomOutputModel>();
        }

        public async Task<int> ChangeStatus(ClassRoomChangeStatus model)
        {
            if (model == null || model.CRoomState.HasValue || model.Id.HasValue)
            {
                throw AppResultException.Status409Conflict("教室状态不能为空！");
            }

            var classRoomInfo = await _context.Set<GardenHouseClassRoom>()
             .Where(m => model.Id == m.Id)
             .FirstOrDefaultAsync();

            if (classRoomInfo == null)
            {
                throw AppResultException.Status404NotFound("未找到教室相关数据，更新失败！");
            }

            classRoomInfo.CRoomState = model.CRoomState ?? true;
            _context.Update(classRoomInfo);
            int ret = await _context.SaveChangesAsync();
            if (ret == 0)
            {
                throw AppResultException.Status200OK("更新记录数为0");
            }

            return ret;

        }
    }
}
